<template>
	<div class="ebook-reader">
		<div id="read">
			
		</div>
	</div>
</template>

<script>
	import { ebookMixin } from '../../utils/mixin.js';
	import { getBookObjectProperty,getLocalStorage } from '../../utils/localstorage.js';
	import { THEME_OPTIONS } from '../../utils/bookStaticData.js';
	import { flatten } from '../../utils/common.js';
	import Epub from 'epubjs';
	global.ePub = Epub;
	export default {
		name: 'ebookReader',
		// 通过 mixins ，使vue在实例化的时候 将EbookReader 和 ebookMixin 进行混合
		mixins:[ebookMixin],
		data() {
			return {
				themeList: THEME_OPTIONS,
				offsetYCount: 0, // 偏移y轴的次数
			}
		},
		methods: {
			// 获取文件名 之后渲染
			getFileNameTheninit() {
				// 获取动态路由
				let fileName = this.$route.params.fileName
				if(fileName) {
					fileName = fileName.split('|').join('/')
					let baseUrl = `${process.env.VUE_APP_RESOURCE_URL}/` 
					let url
					this.setfilename({
						fileName
					}).then(()=> {
						// 因为返回的是promise对象  所以可以调用then方法
						// 组装完整的url
						url =  `${baseUrl}${this.fileName}.epub`
						
						// 渲染图书
						this.initEpub(url)
					})
				}
			},
			/**
			 * 渲染图书的方法
			 * @param {Object} url  完整的需要渲染的epub图书的地址
			 */
			initEpub(url) {
				this.book = new Epub(url)
				// 这里的rendition就变为了渲染对象 
				try {
					this.rendition = this.book.renderTo('read', {
						// readerTo 显示的方法
						// 规定宽高
						width: window.innerWidth,
						height: window.innerHeight,
						// 兼容微信端
						method:'default',
						// 开启 分页以及分页动画
						// flow: 'paginated',
						// manager: 'continuous',
						// snap: true
					})
					
					
					
					this.setcurrentBook({
						currentBook: this.book
					}).then(() => {
						const location = getBookObjectProperty(this.fileName,'location')
						
						this.display(location, () => {
							// 初始化设置图书主题 - 图书内容
							this.initThethme()
							
							// 初始化设置页面主题 - 图书外部（菜单栏等  集成在mixins中）
							this.initPageTheme()
							
							// 初始化设置字体
							this.initSetFontFamily()
							
							// 初始化设置字号
							this.initSetFontSize()
							
							// 解析图书信息（标题，作者，封面等）
							this.parseBook()
							
						})
					})
				}
				catch {
					console.log('捕获到异常')
				}
				
				// 初始化图书手势
				this.initGesture()
				
				this.rendition.hooks.content.register(contents => {
					Promise.all([
						// addStylesheet 返回了一个promise 对象
						contents.addStylesheet(`${process.env.VUE_APP_RESOURCE_URL}/fonts/cabin.css`),
						contents.addStylesheet(`${process.env.VUE_APP_RESOURCE_URL}/fonts/daysOne.css`),
						contents.addStylesheet(`${process.env.VUE_APP_RESOURCE_URL}/fonts/montserrat.css`),
						contents.addStylesheet(`${process.env.VUE_APP_RESOURCE_URL}/fonts/tangerine.css`)
					]).then(() => {
						console.log('字体文件加载完毕')
					})
				})
				//  分页  需要电子书解析全部完成后才能进行 而 ready函数会在book 对象完全解析完成后会调用;
				this.book.ready.then(() => {
					// 分页算法  这里的分页较为粗糙
					return this.book.locations.generate(750 * (window.innerWidth / 375) 
						* (this.defaultFontSize / 16)).then(() => {
							// 当前图书解析完成
							this.setbookAvailable({
								bookAvailable: true
							}).then(() => {
								this.refreshLocation()
							})
						})
				})
			},
			// 初始化图书手势
			initGesture() {
				// epub电子书的实现是基于ifame  而on事件可以去监听iframe
				this.rendition.on('touchstart', event => {
					this.opeartion = ''
					this.touchstartX = event.changedTouches[0].clientX
					this.touchstartY = event.changedTouches[0].clientY
					this.touchStartTime =  event.timeStamp
				})
				
				this.rendition.on('touchend', event => {
					// 事件间隔
					const time = event.timeStamp - this.touchStartTime
					if(this.opeartion === 'down') {
						this.setoffsetY({
							offsetY: 0
						})
						this.offsetYCount = 0;
						this.opeartion = '';
						return
					}else {
						// x轴的偏移量
						const offsetX = event.changedTouches[0].clientX - this.touchstartX
						
						if(time < 500 & offsetX > 40) {
							this.prePage()
						} else if(time < 500 &&offsetX < -40) {
							this.nextPage()
						} else {
							this.toggleTitleAndMenu()
						}
					}

					// 禁止原生事件
					event.preventDefault()
					// 禁止向上传递
					event.stopPropagation()
				})
				
				this.rendition.on('touchmove', event => {
					// 当目录显示时  禁用书签操作
					if(this.menuVisble) {
						return
					}
					
					const offsetY = event.changedTouches[0].clientY - this.touchstartY
					if(offsetY < 0) {
						this.offsetYCount = 0;
						this.opeartion = '';
						return;
					}
					
					if(offsetY > 5) {
						this.offsetYCount++;
					}
					if(this.offsetYCount > 2) {
						this.opeartion = 'down'
						this.setoffsetY({
							offsetY
						})
					}
				})
				
			},
			
			prePage() {
				if(this.rendition) {
					this.rendition.prev().then(()=>{
						this.refreshLocation()
						this.hideTitleAndMenu()
					})
					
				}
			},
			nextPage() {
				if(this.rendition) {
					this.rendition.next().then(()=>{
						this.refreshLocation()
						this.hideTitleAndMenu()
					})
					
				}
			},
			// 显示或隐藏菜单
			toggleTitleAndMenu() {
				//  a. 通过mapActions 可以  简化了代码 this.xxx 直接调用 actions 方法
				// 	b. 想象这样一个场景，需要获取许多的 state的值 和 actions 方法，那么在本页就会写许多的值 难以维护。 通过mixin混入之后, 不需要再本页面写 mapActions 而是统一到 mixin.js 去维护 
				this.setmenuVisble({
					menuVisble : !this.menuVisble
				})
				
				if(!this.menuVisble) {
					this.setsettingVisible({
						settingVisible : -1
					})
					this.setfontFamilyVisible({
						fontFamilyVisible : false
					})
				}
				
			},
			// 隐藏菜单
			hideTitleAndMenu() {
				this.setmenuVisble({
					menuVisble : false
				})
				this.setsettingVisible({
					settingVisible : -1
				})
				this.setfontFamilyVisible({
					fontFamilyVisible : false
				})
			},
			
			// 解析电子书 获取封面，标题，作者等基本信息
			parseBook() {
				// 获取封面路径
				this.currentBook.loaded.cover.then(cover => {
					// 这里的的得到的cover并不是一个url或二进制
					this.currentBook.archive.createUrl(cover).then(url => {
						this.setcoverUrl({
							coverUrl: url
						})
					})
				})
				
				// 获取电子书基本信息
				this.currentBook.loaded.metadata.then(metadata => {
					this.setmetaData({
						metaData: metadata
					})
				})
				
				// 获取电子书目录
				this.currentBook.loaded.navigation.then(nav => {
					if(nav.toc) {
						// 拍扁数据结构
						const navItem = flatten(nav.toc)
						
						// 添加level属性
						const find = function (item, level = 0) {
							return !item.parent ? level : find(navItem.filter(parentItem => parentItem.id === item.parent)[0],++level)
						}
						navItem.forEach(item => {
							item.level = find(item)
						})
						
						this.setnavigation({
							navigation: navItem
						})
					}
				})
			},

			
			// 初始化设置图书主题
			initThethme() {
				let currentThethme = getLocalStorage('defaultTheme')
				if(!currentThethme) {
					currentThethme = this.themeList[0].name
				}
				this.setdefaultTheme({
					defaultTheme: currentThethme
				}).then(() => {
					this.themeList.forEach(item => {
						this.currentBook.rendition.themes.register(item.name, item.style)
					})
					
					this.currentBook.rendition.themes.select(this.defaultTheme)
				})
			},
				
			
			// 初始化设置字体
			initSetFontFamily() {
				let currentFontFamily = getBookObjectProperty(this.fileName,'defaultFontFamily')
				if(currentFontFamily) {
					this.setdefaultFontFamily({
						defaultFontFamily: currentFontFamily
					})
					this.currentBook.rendition.themes.font(this.defaultFontFamily)
				}
			},
			// 初始化设置字号
			initSetFontSize() {
				let currentFontSize = getBookObjectProperty(this.fileName,'defaultFontSize')
				if(currentFontSize) {
					this.setdefaultFontSize({
						defaultFontSize: currentFontSize
					})
					this.currentBook.rendition.themes.fontSize(this.defaultFontSize)
				}
			}
		},
		mounted() {
			// sport|live
			this.getFileNameTheninit()
			
			// let nav = [{
			// 	id: '1',
			// 	subitems:[]
			// },{
			// 	id: '2',
			// 	subitems: [{
			// 		id: '2.1',
			// 		subitems:[{
			// 			id:'2.1.1',
			// 			subitems:[{
			// 				id:'2.1.1.1',
			// 				subitems:[]
			// 			}]
			// 		}]
			// 	}]
			// },{
			// 	id:'3',
			// 	subitems:[]
			// },{
			// 	id:'4',
			// 	subitems:[]
			// },{
			// 	id:'5',
			// 	subitems:[{
			// 		id:'5.1',
			// 		subitems:[]
			// 	},{
			// 		id:'5.2',
			// 		subitems:[]
			// 	}]
			// }];
			
			// let handleNav = flatten(nav)
			// console.log(handleNav)
			
		}
	}
</script>

<style lang="scss" scoped>
	@import '@/assets/styles/global.scss';


</style>
